﻿using DGZImp.Core.Extensions;
using DGZImp.Core.Services;
using DGZImp.MdsProject.Devices.Models;
using DGZImp.MdsProject.Helper;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DGZImp.MdsProject.Devices.Base
{
    public class HttpServe : IIotServe
    {
        private CancellationTokenSource _cancellationTokenSource;
        private CancellationToken _cancellationToken;

        public string Id { get; set; }
        public string Name { get; set; }
        public string BaseUrl { get; set; }

        public HttpClient Client
        {
            get
            {
                var c = ServiceProviderAccessor.ServiceProvider.GetService<IHttpClientFactory>().CreateClient();
                c.BaseAddress = new Uri(BaseUrl);
                return c;
            }
        }

        /// <summary>
        /// 读取间隔，单位ms
        /// </summary>
        public int ReadInterval { get; set; } = 300;

        /// <summary>
        /// 是否自动读取数据
        /// </summary>
        public bool IsAutoRead { get; set; } = true;

        public HttpRequestModel RequestModel { get; set; }

        public event PlcDataReceiveHandler OnPlcDataReceive;
        public event HttpDataReceiveHandler OnHttpDataReceive;
        public event TcpDataReceiveHandler OnTcpDataReceive;
        public event WebSocketDataReceiveHandler OnWebSocketDataReceive;

        public HttpServe(string id, string name, string baseUrl, bool isAutoRead = false, int readInterval = 300, string requestModel = null)
        {
            Id = id;
            Name = name;
            BaseUrl = baseUrl;
            ReadInterval = readInterval;
            IsAutoRead = isAutoRead;
            if (!string.IsNullOrEmpty(requestModel))
                RequestModel = JsonConvert.DeserializeObject<HttpRequestModel>(requestModel);
            _cancellationTokenSource = new CancellationTokenSource();
            _cancellationToken = _cancellationTokenSource.Token;
            StartReadingAsync().ConfigureAwait(false);
        }

        public async Task StartReadingAsync()
        {
            while (!_cancellationToken.IsCancellationRequested)
            {
                var datas = new ConcurrentDictionary<string, byte[]>();
                await Task.Delay(ReadInterval, _cancellationToken);
                if (!IsAutoRead)
                {
                    continue;
                }
                if (RequestModel == null)
                {
                    continue;
                }
                try
                {
                    var res = await SendRequestAsync(RequestModel);
                    OnHttpDataReceive?.Invoke(this, res);
                }
                catch (OperationCanceledException)
                {
                    // 处理取消请求
                }
                catch (Exception e)
                {
                    SysLogger.LogError(e, $"Http服务{Id}读取数据失败");
                }
            }
        }

        public async Task<string> SendRequestAsync(HttpRequestModel req)
        {

            if (req == null)
            {
                throw new Exception("Http请求内容为空");
            }
            try
            {
                if (string.IsNullOrEmpty(req.Path))
                    throw new Exception("Http请求路径为空");
                else if (string.IsNullOrEmpty(req.Method))
                    throw new Exception("Http请求Method为空");
                // 对要求唯一的请求码的特殊处理
                var bodyStr = req.Body;
                if (req.Body.Contains("\"*SimpleSnowId*\""))
                {
                    bodyStr = req.Body.Replace("\"*SimpleSnowId*\"", SimpleSnowId.GenerateId().ToString());
                }
                var BodyObject = JsonConvert.DeserializeObject<object>(bodyStr);
                var res = "";
                var paramsObj = new { };

                //SysLogger.LogInformation($"Http服务{Id}发送请求：Path={req.Path},Method={req.Method},Body={bodyStr}");
                //long startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

                if (req.Method.ToLower() == "post")
                {
                    res = await Client.HttpPostAsync(req.Path, paramsObj, BodyObject, req.ContentType, req.Headers);
                }
                else if (req.Method.ToLower() == "get")
                    res = await Client.HttpGetAsync(req.Path, paramsObj, req.Headers);

                //long endTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                //long durationMilliseconds = endTime - startTime;
                //SysLogger.LogInformation($"获取AGV状态，响应时间：{durationMilliseconds}ms");
                //SysLogger.LogInformation($"返回结果：{res}");

                return res;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public void Dispose()
        {
            _cancellationTokenSource?.Dispose();
        }
    }

    public class HttpRequestModel
    {
        public string Path { get; set; }
        public string Method { get; set; } = "get";
        public HttpContentType ContentType { get; set; } = HttpContentType.Json;
        public Dictionary<string, object> Params { get; set; } = new Dictionary<string, object>();
        public string Body { get; set; } = "{}";
        public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
    }
}
